package com.tanovo.config;

import com.tanovo.bo.ResultObject;
import com.tanovo.constants.CodeConstants;
import com.tanovo.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.stream.Collectors;

@RestControllerAdvice
@Slf4j
public class ExceptionConfig {
    /**
     * 业务异常大于0
     *
     * @param serviceException
     * @return
     */
    @ExceptionHandler(ServiceException.class)
    public ResultObject setServiceException(ServiceException serviceException) {
        log.error("业务异常：{}",serviceException.getMessage(), serviceException);
        ResultObject resultObject = new ResultObject();
        if(StringUtils.isNotBlank(serviceException.getCode())){
            resultObject.setCode(serviceException.getCode());
        }else {
            resultObject.setCode(CodeConstants.SERVICE_ERROR);
        }
        resultObject.setMessage(serviceException.getMessage());
        return resultObject;
    }

    /**
     * 运行时异常小于0
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(Exception.class)
    public ResultObject setException(Exception exception) {
        log.error("运行时异常：{}",exception.getMessage(), exception);
        ResultObject resultObject = new ResultObject();
        resultObject.setCode(CodeConstants.RUN_ERROR);
        resultObject.setMessage(exception.getLocalizedMessage());
        return resultObject;
    }

    /**
     * 全局异常捕捉处理
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultObject handleBindException(MethodArgumentNotValidException ex) {

        // 同样是获取BindingResult对象，然后获取其中的错误信息
        // 如果前面开启了fail_fast，事实上这里只会有一个信息
        //如果没有，则可能又多个
        List<String> errorInformation = ex.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        ResultObject resultObject = new ResultObject();
        resultObject.setCode(CodeConstants.SERVICE_ERROR);
        resultObject.setMessage(errorInformation.toString());
        return resultObject;
    }

}
